package com.hangzhou.xyj.net.handler.base;

import android.content.Context;
import android.util.Log;

import com.android.volley.AuthFailureError;
import com.android.volley.NetworkError;
import com.android.volley.NoConnectionError;
import com.android.volley.ParseError;
import com.android.volley.Response;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.hangzhou.xyj.R;
import com.hangzhou.xyj.XYJApplication;
import com.hangzhou.xyj.event.ServerRespEvent;
import com.hangzhou.xyj.event.base.EventCode;
import com.hangzhou.xyj.net.listener.HttpResponseListener;
import com.hangzhou.xyj.net.listener.base.BaseHttpListener;
import com.hangzhou.xyj.net.request.base.BaseRequest;
import com.hangzhou.xyj.net.response.base.BaseResponse;
import com.hangzhou.xyj.utils.EventBusUtil;
import com.hangzhou.xyj.utils.constants.Constants;

import java.util.Map;


/**
 * Created by DT-038 on 2015/12/20.
 * 服务器返回数据的处理器基类
 */
public abstract class BaseHttpHandler implements Response.Listener<JsonObject>, Response.ErrorListener {

    private static final String TAG = "BaseHttpHandler";

    protected BaseHttpListener mListener;//回调接口
    protected int mTag;
    private Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
    private Context mContext;
    private BaseRequest mRequest;

    public BaseHttpHandler(BaseRequest request, HttpResponseListener listener, int tag) {
        this.mRequest = request;
        this.mListener = listener;
        this.mTag = tag;
        mContext = XYJApplication.getInstance();
    }

    public void onStart() {
        Log.d(TAG, "BaseHttpHandler  onRequest---->" + getRequest().getUrl());
        Map<String, Object> params = mRequest.getParams();
        Log.d(TAG, "BaseHttpHandler  params---->" + gson.toJson(params));
        if (mListener != null) {
            mListener.onResponse(HttpResponseListener.RESPONSE_START, mRequest, mTag);
        }
    }


    @Override
    public void onResponse(JsonObject response) {
        Log.d(TAG, "BaseHttpHandler  onResponse---->" + response);

        //发送一个服务器返回数据成功的Event
        ServerRespEvent event = new ServerRespEvent();
        event.setCode(EventCode.SUCCESS);
        event.setApi(mRequest.getUrl());
        event.setData(response);
        EventBusUtil.postEvent(event);
        BaseResponse resp = null;
        try {
            //服务器返回的是BaseResponse结构则用BaseResponse处理
            if (getResponseClazz().newInstance() instanceof BaseResponse) {
                resp = (BaseResponse) gson.fromJson(response, getResponseClazz());
            } else {    //否则直接回调服务器数据（针对非BaseResponse结构）
                if (mListener != null) {
                    mListener.onResponse(HttpResponseListener.RESPONSE_SUCCESS, gson.fromJson(response, getResponseClazz()), mTag);
                }
                return;
            }
        } catch (Exception e) {
            if (e != null) {
                Log.e(TAG, e.getMessage());
            }
            if (mListener != null) {
                mListener.onResponse(HttpResponseListener.RESPONSE_DONE,
                        mContext.getResources().getString(R.string.tip_server_unavailable_data), mTag);
                return;
            }
        }
        if (resp != null && resp.isSuccess()) {
            if (mListener != null) {
                mListener.onResponse(HttpResponseListener.RESPONSE_SUCCESS, resp.getData(), mTag);
            }
        } else {
            if (mListener != null)
                mListener.onResponse(HttpResponseListener.RESPONSE_FAIL,
                        (resp == null) ? mContext.getResources().getString(R.string.tip_load_data_failed)
                                : resp.getMsg(), mTag);
        }
    }

    @Override
    public void onErrorResponse(VolleyError error) {
        if (error != null) {
            Log.d(TAG, "BaseHttpHandler  onErrorResponse---->" + error.getMessage());
        }
        /*以下是Volley的异常列表：
        AuthFailureError：如果在做一个HTTP的身份验证，可能会发生这个错误。
        NetworkError：Socket关闭，服务器宕机，DNS错误都会产生这个错误。
        NoConnectionError：和NetworkError类似，这个是客户端没有网络连接。
        ParseError：在使用JsonObjectRequest或JsonArrayRequest时，如果接收到的JSON是畸形，会产生异常。
        SERVERERROR：服务器的响应的一个错误，最有可能的4xx或5xx HTTP状态代码。
        TimeoutError：Socket超时，服务器太忙或网络延迟会产生这个异常。默认情况下，Volley的超时时间为2.5秒。如果得到这个错误可以使用RetryPolicy。
        */
        if (mListener != null) {
            String errorMessage = "";
            if (error instanceof AuthFailureError) {
                //unknown
            } else if (error instanceof NetworkError) {
                errorMessage = mContext.getResources().getString(R.string.tip_server_on_busy);
            } else if (error instanceof NoConnectionError) {
                errorMessage = mContext.getResources().getString(R.string.tip_net_error);
            } else if (error instanceof ParseError) {
                errorMessage = mContext.getResources().getString(R.string.tip_server_unavailable_data);
            } else if (error instanceof TimeoutError) {
                errorMessage = mContext.getResources().getString(R.string.tip_server_on_busy);
            }
            mListener.onResponse(HttpResponseListener.RESPONSE_FAIL,
                    errorMessage + (Constants.DEBUG ? error.getMessage() : ""), mTag);
        }
    }

    /**
     * 网络异常
     */
    public void onNetWorkErrorResponse() {
        if (mListener != null) {
            mListener.onResponse(HttpResponseListener.RESPONSE_ERROR,
                    XYJApplication.getInstance().getResources().getString(R.string.tip_net_error), mTag);
        }
    }

    /**
     * 获取请求对象
     *
     * @return
     */
    public BaseRequest getRequest() {
        return mRequest;
    }

    public abstract Class<?> getResponseClazz();
}
